﻿using Acr.UserDialogs;
using RaceHFTools.BluetoothLE.Bean;
using RaceHFTools.BluetoothLE.Bean.Module;
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace RaceHFTools.Pages
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class FsyncPage : ContentPage
    {
        private readonly Bean bean;

        private class FileInfo
        {
            public FileItem File { get; private set; }

            public string Name { get => File.Name; }

            public string Detail
            {
                get
                {
                    string ststr = string.Empty;
                    if (File.Type == FSYNC_PATH_TYPE.DIRECTORY)
                        ststr = "Directory";
                    else if (File.Type == FSYNC_PATH_TYPE.FILE)
                        ststr = $"File:{(File.Size + 1023) / 1024}KB";

                    return ststr;
                }
            }

            public FileInfo(FileItem file)
            {
                File = file;
            }
        }

        private const string root_path = "/";
        private readonly ObservableCollection<FileInfo> ListViewSource = new ObservableCollection<FileInfo>();
        private string fsync_path = root_path;

        public FsyncPage(Bean bean)
        {
            InitializeComponent();

            this.bean = bean;
            lvFileList.ItemsSource = ListViewSource;
        }

        #region OnAppearing/OnDisappearing
        protected override void OnAppearing()
        {
            base.OnAppearing();

            fsync_path = root_path;
            lvFileList.BeginRefresh();
        }

        protected override void OnDisappearing()
        {
            base.OnDisappearing();
        }
        #endregion

        #region 交互事件
        void Button_GoBackFolder_Clicked(object sender, EventArgs e)
        {
            string[] paths = fsync_path.Split(new char[] { '/' });
            fsync_path = root_path + string.Join("/", paths, 0, paths.Length - 1);
            RefreshFileListHandler(fsync_path);
        }

        void Button_GoRootFolder_Clicked(object sender, EventArgs e)
        {
            fsync_path = root_path;
            RefreshFileListHandler(fsync_path);
        }

        void ListView_FileList_ItemTapped(object sender, ItemTappedEventArgs e)
        {
            FileInfo item = e.Item as FileInfo;

            if (item.File.Type == FSYNC_PATH_TYPE.DIRECTORY)
            {
                if (fsync_path.Last() != '/')
                    fsync_path += "/";
                fsync_path += item.File.Name;

                RefreshFileListHandler(fsync_path);
            }
            else if (item.File.Type == FSYNC_PATH_TYPE.FILE)
            {
                string local = Path.Combine(Utils.File.Root, item.File.Name);
                string remote = fsync_path;

                if (remote.Last() != '/')
                    remote += "/";
                remote += item.File.Name;

                SyncFileHandler(remote, local);
            }
        }

        void ListView_FileList_Refreshing(object sender, EventArgs e)
        {
            RefreshFileListHandler(fsync_path);
            lvFileList.EndRefresh();
        }
        #endregion

        #region 事件处理
        void RefreshFileListHandler(string path)
        {
            Task.Run(async () =>
            {
                FileItem[] items;
                CancellationTokenSource cts = new CancellationTokenSource();
                using (var loading = UserDialogs.Instance.Loading("同步准备中", cts.Cancel, "[取消]"))
                {
                    items = await bean.Fsync.ReadFileList(path, (process, percent) => loading.Title = process, cts.Token);
                }

                ListViewSource.Clear();
                foreach (FileItem x in items)
                {
                    FileItem t = x;
                    t.Name = t.Name.Split(new char[] { '\0' })[0];
                    ListViewSource.Add(new FileInfo(t));
                }
            });
        }

        void SyncFileHandler(string remote, string local)
        {
            Task.Run(async () =>
            {
                byte[] data;
                CancellationTokenSource cts = new CancellationTokenSource();
                using (var progress = UserDialogs.Instance.Progress("同步准备中", cts.Cancel, "[取消]"))
                {
                    void show_process(string process, int percent)
                    {
                        progress.Title = process;
                        progress.PercentComplete = percent;
                    }
                    data = await bean.Fsync.SyncFile(remote, show_process, cts.Token);
                }

                if (data != null)
                {
                    File.WriteAllBytes(local, data);
                    Device.BeginInvokeOnMainThread(async () => await DisplayAlert("文件同步成功", $"保存在:{local}", "确定"));
                }
                else
                {
                    Device.BeginInvokeOnMainThread(async () => await DisplayAlert("", "文件同步失败", "确定"));
                }
            });
        }
        #endregion
    }
}
